home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-04 / vballs11.zip / BALLS3.C < prev    next >
C/C++ Source or Header  |  1991-03-06  |  5KB  |  274 lines

  1. /*
  2.  * balls3.c - Attempt to draw balls in VGA256 mode
  3.  *
  4.  *             Uses BGI interface
  5.  *
  6.  * Adapted by: Scott J. Walter (GEnie:  S.Walter4)
  7.  *            
  8.  */
  9.  
  10. /* INCLUDES */
  11.  
  12. #include <stdio.h>
  13. #include <dos.h>
  14. #include <math.h>
  15. #include <graphics.h>
  16. #include <stdlib.h>
  17. #include <conio.h>
  18. #include <alloc.h>
  19. #include <mem.h>
  20. #include <bios.h>
  21. #include <time.h>
  22.  
  23.  
  24.  
  25. /* DEFINES */
  26.  
  27. #define DIM   3                /* number of dimensions        */
  28. #define TRUE  1
  29. #define FALSE 0
  30.  
  31. typedef unsigned char UBYTE;
  32.  
  33. typedef double VECTOR [DIM];
  34.  
  35. typedef struct {
  36.            UBYTE Rvalue;
  37.            UBYTE Gvalue;
  38.            UBYTE Bvalue;
  39.            } ColorValue;
  40.  
  41.  
  42.  
  43. /* PROTOTYPES */
  44.  
  45. int huge DetectVGA256(void);
  46. void     VGASetAllPalette(UBYTE far *pal);
  47. void     Hsi2Rgb(float H, float S, float I, ColorValue *C);
  48. void     normalize (VECTOR this_vec);
  49. double   dot_prod (VECTOR vec1, VECTOR vec2);
  50. void     put_atom(int R, int index, int xc, int yc, VECTOR l_source);
  51.  
  52.  
  53.  
  54.  
  55.  
  56.  
  57. void put_atom(int R, int index, int xc, int yc, VECTOR l_source)
  58. {
  59.  VECTOR s_point;
  60.  int R2, color = 0;
  61.  double x,y,z,r,intensity;
  62.  
  63.  
  64.  normalize(l_source);               /* normalize the light source    */
  65.  R2=R*R;                            /* only calculate R*R once     */
  66.  for (x=-R;x<=+R;x=x+1)             /* scan an area 2R x 2R     */
  67.   {
  68.   for (y=-R;y<=+R;y=y+1)
  69.    {
  70.    r=(x*x)+(y*y);             /* check that the pixel is within a     */
  71.    if (r <= R2)               /* circle of radius R               */
  72.     {
  73.     z=sqrt((R2)-r);            /* calculate the altitude of the point     */
  74.     s_point[0]= x;             /* set the normal surface vector to the */
  75.     s_point[1]= y;             /* coordinates of the point         */
  76.     s_point[2]= z;
  77.  
  78.     intensity  = random(100);
  79.     intensity /= 100;
  80.  
  81.     intensity += 64 * dot_prod(s_point,l_source)/R;
  82.  
  83.     color = (int)intensity;
  84.  
  85.     color = color<0 ? 0 : (color> 63 ? 63 : color);
  86.  
  87.     putpixel(x+xc,y+yc,index*64 + color);
  88.     }
  89.    }
  90.   }
  91. }
  92.  
  93.  
  94.  
  95. /*
  96.  * Normalize a vector to unit magnitude.  Calculate the magnitude as:
  97.  *
  98.  *     magnitude = sqrt ( x^2 + y^2 + z^2 )
  99.  *
  100.  * Normalize the vector by dividing each coordinate by the magnitude.
  101.  * FOR loops are used to maintain generality--any dimension vector may
  102.  * be normalized by changing DIM.
  103.  */
  104. void normalize (VECTOR this_vec)
  105. {
  106.  double mag;
  107.  int count;
  108.  
  109.  
  110.  mag = 0.0;
  111.  
  112.  for (count = 0; count < DIM; count++)
  113.   mag = mag + (this_vec [count] * this_vec [count]);
  114.  
  115.  mag = sqrt(mag);
  116.  
  117.  for (count = 0; count < DIM; count++)
  118.   this_vec [count] = this_vec [count]/mag;
  119. }
  120.  
  121.  
  122.  
  123. /* Calculate the cosine of the angle between two vectors.
  124.  *
  125.  *     dot product = (x1 * x2) + (y1 * y2) + (z1 * z2)
  126.  */
  127. double dot_prod (VECTOR vec1, VECTOR vec2)
  128. {
  129.  double COSINE;
  130.  int count;
  131.  
  132.  
  133.  COSINE = 0.0;
  134.  
  135.  for (count = 0; count < DIM; count++)
  136.   COSINE += vec1 [count] * vec2 [count];
  137.  
  138.  return (COSINE);
  139. }
  140.  
  141.  
  142.  
  143. void VGASetAllPalette(pal)
  144. UBYTE far *pal;
  145. {
  146.  struct REGPACK r;
  147.  
  148.  
  149.  r.r_ax = 0x1012;
  150.  r.r_bx = 0x0000;
  151.  r.r_cx = 0x0100;
  152.  r.r_es = FP_SEG(pal);
  153.  r.r_dx = FP_OFF(pal);
  154.  
  155.  intr(0x10, &r);
  156. }
  157.  
  158.  
  159.  
  160. void Hsi2Rgb(float H, float S, float I, ColorValue *C)
  161. {
  162.  float T, Rv, Gv, Bv;
  163.  float Pi = 3.14159265358979;
  164.  
  165.  
  166.  if(H<0.0)
  167.   H = 1.0 + H;
  168.  
  169.  if(H>1.0)
  170.   H = H - 1.0;
  171.  
  172.  T  = 2.0 * Pi * H;
  173.  
  174.  Rv = 1 + S * sin(T - 2 * Pi / 3);
  175.  Gv = 1 + S * sin(T);
  176.  Bv = 1 + S * sin(T + 2 * Pi / 3);
  177.  
  178.  T = 63.999 * I / 2;
  179.  
  180.  C->Rvalue = (UBYTE)(Rv * T);
  181.  C->Gvalue = (UBYTE)(Gv * T);
  182.  C->Bvalue = (UBYTE)(Bv * T);
  183. }
  184.  
  185.  
  186.  
  187. int huge DetectVGA256()
  188. {
  189.  int gdriver, gmode;
  190.  
  191.  
  192.  detectgraph(&gdriver, &gmode);
  193.  
  194.  if((gdriver==VGA)||(gdriver==MCGA))
  195.    return 0;                    /* Default video mode = 0 */
  196.  else
  197.    return grError;             /* Couldn't detect hardware */
  198. }
  199.  
  200.  
  201.  
  202.  
  203. /* MAIN */
  204.  
  205. void main()
  206. {
  207.  int   Y, Z, ErrorCode, Driver = DETECT, Mode;
  208.  int radius  = 40;
  209.  VECTOR light = { -2.0, -2.0, 3.0 };    /* light source from upper left */
  210.  UBYTE far *pal;
  211.  UBYTE far *t;
  212.  ColorValue C;
  213.  unsigned sseg1, sseg2, soff1, soff2, dseg, doff;
  214.  
  215.  
  216.  installuserdriver("VGA256", DetectVGA256);
  217.  
  218.  initgraph(&Driver, &Mode, "");
  219.  
  220.  ErrorCode = graphresult();
  221.  
  222.  if(ErrorCode!=grOk)
  223.   {
  224.   printf("Error: %s\n", grapherrormsg(ErrorCode));
  225.   exit(1);
  226.   }
  227.  
  228.  randomize();
  229.  
  230.  pal = (UBYTE far *)farmalloc(768);
  231.  t   = (UBYTE far *)farmalloc(192);
  232.  
  233.  sseg1 = FP_SEG(pal+576);  soff1 = FP_OFF(pal+576);
  234.  sseg2 = FP_SEG(pal);      soff2 = FP_OFF(pal);
  235.  dseg  = FP_SEG(t);        doff  = FP_OFF(t);
  236.  
  237.  for(Y=0;Y<5;Y++)
  238.   for(Z=0;Z<64;Z++)
  239.    {
  240.    Hsi2Rgb((float)Y/5.0, 1.0, (float)Z/64.0, &C);
  241.  
  242.    *(pal+Y*192+Z*3+0) = C.Rvalue;
  243.    *(pal+Y*192+Z*3+1) = C.Gvalue;
  244.    *(pal+Y*192+Z*3+2) = C.Bvalue;
  245.    }
  246.  
  247.  VGASetAllPalette(pal);
  248.  
  249.  for(Y=0;Y<2;Y++)
  250.   for(Z=0;Z<2;Z++)
  251.    put_atom(radius, Y*2+Z, 80+160*Z, 50+100*Y, light);
  252.  
  253.  do
  254.   {
  255.   movedata(sseg1, soff1, dseg, doff, 192);
  256.  
  257.   for(Y=2;Y>=0;Y--)
  258.    movedata(FP_SEG(pal+192*Y)    , FP_OFF(pal+192*Y),
  259.         FP_SEG(pal+192*(Y+1)), FP_OFF(pal+192*(Y+1)), 192);
  260.  
  261.   movedata(dseg, doff, sseg2, soff2, 192);
  262.  
  263.   VGASetAllPalette(pal);
  264.  
  265.   } while(!bioskey(1));
  266.  
  267.  getch();
  268.  
  269.  farfree((void far *)pal);
  270.  farfree((void far *)t);
  271.  
  272.  closegraph();
  273. }
  274.